/*
******************************************************************************
**
**  File        : LinkerScript.ld
**
**  Author		: Auto-generated by STM32CubeIDE
**
**  Abstract    : Linker script for NUCLEO-L152RE Board embedding STM32L152RETx Device from STM32L1 series
**                      512Kbytes FLASH
**                      80Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**   1. Redistributions of source code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**   2. Redistributions in binary form must reproduce the above copyright notice,
**      this list of conditions and the following disclaimer in the documentation
**      and/or other materials provided with the distribution.
**   3. Neither the name of STMicroelectronics nor the names of its contributors
**      may be used to endorse or promote products derived from this software
**      without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

/* Entry Point. */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack. */
_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of "RAM" Ram type memory. */

_Min_Heap_Size = 0x200 ;        /* Required amount of heap. */
_Min_Stack_Size = 0x400 ;       /* Required amount of stack. */

/* Memories definition. */
/* ARMv7M MPU requires that the base address of a MPU region must be aligned to
 * an interger mutiple of the region size and the region size can only be a
 * power of 2. We, therefore, are not using last 16K of RAM. */
MEMORY
{
    RAM (xrw)           : ORIGIN = 0x20000000,  LENGTH = 64K
    RAM_UNUSED (xrw)    : ORIGIN = 0x20010000,  LENGTH = 16K
    FLASH (rx)          : ORIGIN = 0x8000000,   LENGTH = 512K
}

/* Initial 32K Flash is used to store kernel functions and
 * initial 512 bytes of RAM is used to store kernel data. */
__privileged_functions_region_size__  = 32K;
__privileged_data_region_size__       = 512;

__FLASH_segment_start__               = ORIGIN( FLASH );
__FLASH_segment_end__                 = __FLASH_segment_start__ + LENGTH( FLASH );

__SRAM_segment_start__                = ORIGIN( RAM );
__SRAM_segment_end__                  = __SRAM_segment_start__ + LENGTH( RAM );

__privileged_functions_start__        = __FLASH_segment_start__;
__privileged_functions_end__          = __FLASH_segment_start__ + __privileged_functions_region_size__;

__privileged_data_start__             = __SRAM_segment_start__;
__privileged_data_end__               = __SRAM_segment_start__ + __privileged_data_region_size__;

/* Sections. */
SECTIONS
{
    /* The startup code and FreeRTOS kernel code are placed into privileged
     * flash. */
    .privileged_functions :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */
        . = ALIGN(4);
        *(privileged_functions)
        . = ALIGN(4);
        FILL(0xDEAD);
        /* Ensure that un-privileged code is placed after the region reserved
         * for privileged kernel code. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_functions in this case). As a
         * result, setting dot (.) to a value sets the size of the section. */
        . = __privileged_functions_region_size__;
    } >FLASH

    /* The rest of the program code and other data into the remaining
     * unprivileged flash. */
    .text :
    {
        /* Place the FreeRTOS System Calls first in the unprivileged region. */
        . = ALIGN(4);
        __syscalls_flash_start__ = .;
        *(freertos_system_calls)
        __syscalls_flash_end__ = .;
        . = ALIGN(4);
        *(.text)           /* .text sections (code). */
        *(.text*)          /* .text* sections (code). */
        *(.glue_7)         /* glue arm to thumb code. */
        *(.glue_7t)        /* glue thumb to arm code. */
        *(.eh_frame)

        KEEP (*(.init))
        KEEP (*(.fini))

        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code. */
    } >FLASH

    /* Constant data into "FLASH" Rom type memory. */
    .rodata :
    {
        . = ALIGN(4);
        *(.rodata)         /* .rodata sections (constants, strings, etc.). */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.). */
        . = ALIGN(4);
    } >FLASH

    .ARM.extab :
    { 
        . = ALIGN(4);
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        . = ALIGN(4);
    } >FLASH
    
    .ARM :
    {
        . = ALIGN(4);
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
        . = ALIGN(4);
    } >FLASH

    .preinit_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array*))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        . = ALIGN(4);
    } >FLASH
    
    .init_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array*))
        PROVIDE_HIDDEN (__init_array_end = .);
        . = ALIGN(4);
    } >FLASH
    
    .fini_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(SORT(.fini_array.*)))
        KEEP (*(.fini_array*))
        PROVIDE_HIDDEN (__fini_array_end = .);
        . = ALIGN(4);
    } >FLASH

    /* Used by the startup to initialize data. */
    _sidata = LOADADDR(.privileged_data);

    /* FreeRTOS kernel data. */
    .privileged_data :
    {
        . = ALIGN(4);
        _sdata = .;        /* Create a global symbol at data start. */
        *(privileged_data)
        . = ALIGN(4);
        FILL(0xDEAD);
        /* Ensure that un-privileged data is placed after the region reserved
         * for privileged kernel data. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_data in this case). As a result,
         * setting dot (.) to a value sets the size of the section. */
        . = __privileged_data_region_size__;
    } >RAM AT> FLASH

    /* Initialized data sections into "RAM" Ram type memory. */
    .data : 
    {
        . = ALIGN(4);
        *(.data)           /* .data sections. */
        *(.data*)          /* .data* sections. */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end. */
    } >RAM AT> FLASH

    /* Uninitialized data section into "RAM" Ram type memory. */
    . = ALIGN(4);
    .bss :
    {
        /* This is used by the startup in order to initialize the .bss section. */
        _sbss = .;         /* define a global symbol at bss start. */
        __bss_start__ = _sbss;
        *(.bss)
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end. */
        __bss_end__ = _ebss;
    } >RAM

    /* User_heap_stack section, used to check that there is enough "RAM" Ram
    * type memory left. */
    ._user_heap_stack :
    {
        . = ALIGN(8);
        PROVIDE ( end = . );
        PROVIDE ( _end = . );
        . = . + _Min_Heap_Size;
        . = . + _Min_Stack_Size;
        . = ALIGN(8);
    } >RAM

    /* Remove information from the compiler libraries. */
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }

    .ARM.attributes 0 : { *(.ARM.attributes) }
}
